﻿using System.Xml.Linq;

namespace EasyXaf.DynamicForm.Models;

public class Panel : FormItem
{
    public string ImageName { get; set; }

    public bool? IsExpanded { get; set; }

    public FlowDirection? Direction { get; set; }

    public List<FormItem> Items { get; }

    public List<Field> Fields
    {
        get
        {
            var fields = new List<Field>();
            foreach (var formItem in Items)
            {
                if (formItem is Field field)
                {
                    fields.Add(field);
                }
                else if (formItem is Panel panel)
                {
                    fields.AddRange(panel.Fields);
                }
                else if (formItem is Group group)
                {
                    fields.AddRange(group.Fields);
                }
                else if (formItem is Tabs tabs)
                {
                    foreach (var tab in tabs.TabPanels)
                    {
                        fields.AddRange(tab.Fields);
                    }
                }
            }
            return fields;
        }
    }

    public Panel(Form form, Element parent)
        : base(form, parent)
    {
        ShowCaption = false;
        Items = [];
    }

    public override void WriteXml(XElement element)
    {
        base.WriteXml(element);

        if (!string.IsNullOrWhiteSpace(ImageName))
        {
            SetXmlAttributeValue(element, "image", ImageName);
        }

        if (IsExpanded.HasValue)
        {
            SetXmlAttributeValue(element, "expanded", IsExpanded.Value);
        }

        if (Direction.HasValue)
        {
            SetXmlAttributeValue(element, "direction", Direction switch
            {
                FlowDirection.Horizontal => "horizontal",
                FlowDirection.Vertical => "vertical",
                _ => null,
            });
        }

        foreach (var formItem in Items)
        {
            var formItemElement = formItem.CreateXElement();
            formItem.WriteXml(formItemElement);
            element.Add(formItemElement);
        }
    }

    public override void ReadXml(XElement element)
    {
        base.ReadXml(element);

        ImageName = GetXmlAttributeValue<string>(element, "image");
        IsExpanded = GetXmlAttributeValue<bool?>(element, "expanded");
        Direction = GetXmlAttributeValue<string>(element, "direction") switch
        {
            "horizontal" => FlowDirection.Horizontal,
            "vertical" => FlowDirection.Vertical,
            _ => null,
        };

        Items.Clear();

        foreach (var formItemElement in element.Elements())
        {
            var elementName = formItemElement.Name.LocalName;
            if (elementName == "panel" || elementName == "hpanel" || elementName == "vpanel")
            {
                var panel = new Panel(Form, this);
                panel.ReadXml(formItemElement);
                panel.Direction = elementName switch
                {
                    "hpanel" => FlowDirection.Horizontal,
                    "vpanel" => FlowDirection.Vertical,
                    _ => null,
                };
                Items.Add(panel);
            }
            else if (elementName == "group" || elementName == "hgroup" || elementName == "vgroup")
            {
                var group = new Group(Form, this);
                group.ReadXml(formItemElement);
                group.Direction = elementName switch
                {
                    "hgroup" => FlowDirection.Horizontal,
                    "vgroup" => FlowDirection.Vertical,
                    _ => null,
                };
                Items.Add(group);
            }
            else if (elementName == "tabs")
            {
                var tabs = new Tabs(Form, this);
                tabs.ReadXml(formItemElement);
                Items.Add(tabs);
            }
            else if (elementName == "table")
            {
                var table = new Table(Form, this);
                table.ReadXml(formItemElement);
                Items.Add(table);
            }
            else if (elementName == "field")
            {
                var field = new Field(Form, this);
                field.ReadXml(formItemElement);
                Items.Add(field);
            }
        }
    }

    public override XElement CreateXElement()
    {
        return Direction switch
        {
            FlowDirection.Horizontal => new XElement("hpanel"),
            FlowDirection.Vertical => new XElement("vpanel"),
            _ => new XElement("panel"),
        };
    }
}
